/*
 * Created on Dec 24, 2003
 *
 * To change the template for this generated file go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */
package ModuleBuilder.UI;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import java.util.Map.Entry;
import ModuleBuilder.*;
import javax.swing.event.*;

import java.beans.*;
import ModuleBuilder.*;
import ModuleBuilder.model.*;


/**
 * @author msoong
 *
 * To change the template for this generated type comment go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 * 
 * Will have the following Layouts: (see diagram on Lab book page 57)
 * 1) Outer most is a Border Layout, with help text NORTH, and rest in the CENTER
 * 2) of the rest of the body, we use BOXLAYOUT (horizontal)
 * 3) on left, VERTICAL BOXLAYOUT
 * 4) on RIGHT, VERTICAL BOXLAYOUT with a Border
 */
public class PictureBuilder extends JPanel 
	implements ActionListener, iFileSelectInput
{
		
	private static JFileChooser fc = new JFileChooser();
	static private String newline = "\n";
	private JTextField tb;
	private ItemList figureList;
	private ImagePreview figurePreview;
	JLabel imageSizeLabel;
	BuilderManager manager;
	Dimension sizeConstraint;	// the input picture must be same or smaller than this size
	
	public PictureBuilder( BuilderManager m, Dimension sizeConstraintIn ) {
		manager = m;
		sizeConstraint = sizeConstraintIn;
		 
		JLabel helpText = 
		new JLabel("Please select the names of all files of the top down image you");
		JLabel helpText1 = 
		new JLabel(" would like to use for your scenario, and add them to the list one at a time");
		
		JLabel fnLabel = new JLabel( "File Name:");			
		//this.add( fnLabel );
		tb = new JTextField();
		//this.add( tb );
		JButton fcButton = new JButton("Browse");
		//this.add(fcButton);		
		fcButton.addActionListener(this);

		figureList = new ItemList( this );
		
		// setup figure preview stuff on the bottom right
		JPanel bottomRightPanel = new JPanel();
		bottomRightPanel.setLayout(new BoxLayout(bottomRightPanel, BoxLayout.PAGE_AXIS));
		imageSizeLabel = new JLabel("No Image Selected");
		figurePreview = new ImagePreview(this, "Image Preview");
		figurePreview.setPictureBuilder(this);
		figureList.addImagePreview(figurePreview);
		figurePreview.setAlignmentX(JComponent.LEFT_ALIGNMENT);
		figurePreview.setAlignmentY(JComponent.TOP_ALIGNMENT);
		bottomRightPanel.add(figurePreview);
		imageSizeLabel.setAlignmentX(JComponent.LEFT_ALIGNMENT);
		bottomRightPanel.add(imageSizeLabel);
		bottomRightPanel.add(Box.createVerticalGlue());

		figurePreview.setImageSize(imageSizeLabel);
		
		
		// First setup the inner ones
		JPanel fnInputPanel = new JPanel();
		fnInputPanel.setLayout(new FlowLayout());
		fnInputPanel.add(fnLabel);
		fnInputPanel.add(tb);
		fnInputPanel.add(fcButton);
		
		// 2nd the left Bottom section
		JPanel leftBottomPanel = new JPanel();
		leftBottomPanel.setLayout(new BoxLayout( leftBottomPanel, BoxLayout.PAGE_AXIS));
		leftBottomPanel.add(Box.createRigidArea(new Dimension(10, 0)));
		leftBottomPanel.add(fnInputPanel);
		leftBottomPanel.add(figureList);
		leftBottomPanel.add(Box.createRigidArea(new Dimension(0, 15)));
							
		// 3rd the bottom section
		JPanel bottomPanel = new JPanel();
		bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.LINE_AXIS));
		bottomPanel.add(Box.createRigidArea(new Dimension(15, 0)));
		bottomPanel.add(leftBottomPanel);
		bottomPanel.add(Box.createRigidArea(new Dimension(10, 0)));
		bottomPanel.add(new JSeparator(SwingConstants.VERTICAL));
		bottomPanel.add(Box.createRigidArea(new Dimension(10, 0)));
		bottomRightPanel.setAlignmentY(JComponent.TOP_ALIGNMENT);
		bottomPanel.add(bottomRightPanel);

		
		// lastly we do the overall layout
		this.setLayout( new BoxLayout(this, BoxLayout.PAGE_AXIS));
		helpText.setAlignmentX(JComponent.LEFT_ALIGNMENT);
		helpText1.setAlignmentX(JComponent.LEFT_ALIGNMENT);

		this.add(helpText);
		this.add(helpText1);
		this.add(Box.createRigidArea(new Dimension(0, 10)));
		this.add(new JSeparator(SwingConstants.HORIZONTAL));
		this.add(Box.createRigidArea(new Dimension(0, 10)));
		bottomPanel.setAlignmentX(JComponent.LEFT_ALIGNMENT);
		this.add(bottomPanel);

		// now need to set some size limitations to the components
		Dimension d = tb.getPreferredSize();
		d.width = 200;
		tb.setMinimumSize(d);
		tb.setPreferredSize(d);
		tb.setMaximumSize(d);
		
		Dimension d1= figureList.getPreferredSize();
		d1.height=d.height*5;
		figureList.setMinimumSize(d1);
		// figureList.setPreferredSize(d1);
		// figureList.setMaximumSize(d1);
							
		validate();			 							 					
	}
	
	public void actionPerformed(ActionEvent e) {
		//Set up the file chooser.
		//Add a custom file filter and disable the default
		//(Accept All) file filter.
		fc.addChoosableFileFilter(new ImageFilter());
		fc.setAcceptAllFileFilterUsed(false);

		//Add custom icons for file types.
		fc.setFileView(new ImageFileView());

		//Add the preview pane.
		fc.setAccessory(new FileChooserImagePreview(fc));

		//Show it.
		int returnVal = fc.showDialog(this, "Select Image");

		//Process the results.
		if (returnVal == JFileChooser.APPROVE_OPTION) {
			File file = fc.getSelectedFile();
			String fn = file.getPath();
			// Debug.out("Attaching file: " + fn + "." + newline);
			tb.setText(fn);
		} else {
			Debug.out("Attachment cancelled by user." + newline);
		}
		//log.setCaretPosition(log.getDocument().getLength());

		//Reset the file chooser for the next time it's shown.
		fc.setSelectedFile(null);
	}
	
	public String getSelectedFilePath() {
		return ( tb.getText() );
	}	
	/**
	 * @return
	 */
	public JLabel getImageSizeLabel() {
		return imageSizeLabel;
	}

	public void imageAdded( ImageElement el ){
		manager.imageAdded(this, el);
	}
	
	public void imageDeleted( ImageElement el ){
		manager.imageDeleted(this, el);
	}
	
	public PictureCollectionModel store() {
		// first get the list of filenames from the ItemList object
		PictureCollectionModel mod = new PictureCollectionModel();
		
		int picCount = figureList.getItemCount();
		for ( int i=0; i< picCount; i++){
			String fn = figureList.getItemName(i);
			ImageElement el = ImageCacheDelegate.getImageElement(fn);
			applySizeConstraint(el, sizeConstraint);
			mod.addPicture(fn, el);
		}
		return (mod);
	}
	
	private void applySizeConstraint( ImageElement el, Dimension sizeConstraint) {
		// only proceed if there is a valid sizeConstraint
		if ( sizeConstraint != null ){
			
			ImageIcon icon = el.getFullImageIcon();
			int iconH = icon.getIconHeight();
			int iconW = icon.getIconWidth();
			int h = sizeConstraint.height;
			int w = sizeConstraint.width;
			
			// see which dimension is the "defining" dimension by meansuring the size ratio
			double ratioH = iconH / h;
			double ratioW = iconW / w;
			ImageIcon adjustedIcon=null;
			if ( ratioH > ratioW ){
				// height is the defining dimension
				adjustedIcon = new ImageIcon(	icon.getImage().
										getScaledInstance(
											-1, 
											h,
											Image.SCALE_DEFAULT  ));
			} else {
				adjustedIcon = new ImageIcon(	icon.getImage().
										getScaledInstance(
											w, 
											-1,
											Image.SCALE_DEFAULT  ));
				
			}
			el.setFullImageIcon(adjustedIcon);
		}
		return;
	}
	
	public void load( PictureCollectionModel mod ) {
		HashMap allPixHash = mod.getPictures();
		Iterator it = allPixHash.entrySet().iterator();
		while( it.hasNext()) {
			Map.Entry e = (Map.Entry)it.next();
			String fn = (String)e.getKey();
			ImageElement el = (ImageElement)e.getValue();
			ImageIcon imageIcon = el.getFullImageIcon();
			Image storedImg = imageIcon.getImage();
			imageIcon.setImage(storedImg);

			el.makeSmallIconFromLarge();
			
			// now add to the image cache and to the item list
			ImageCacheDelegate.addImageElement(fn, el);
			figureList.addItemToList(fn);
			
			// now inform the manager
			imageAdded(el);
		}
		return;
	}
 }
